package course_9_2.eg.hw.no1;

import java.util.InputMismatchException;
import java.util.LinkedList;
import java.util.Scanner;
class KeyboardInput {
	static Scanner scanner = new Scanner(System.in);
	public int readInt(String prompt) {
		int value ;
		while (true){
			try {
				System.out.print(prompt);
				value = scanner.nextInt();
				break;
			} catch (InputMismatchException e) {
				System.out.println("输入错误，请重新输入整数。");
			}
			finally {
				scanner.nextLine();
			}
		}
		return value;
	}
	public double readDouble(String prompt) {
		double value = 0;
		while (true){
			try {
				System.out.print(prompt);
				value = scanner.nextDouble();
				break;
			} catch (InputMismatchException e) {
				System.out.println("输入错误，请重新输入小数。");
				scanner.nextLine();
			}
		}
		return value;
	}
	public String readString(String prompt) {
		String value;
		while (true){
			try {
				System.out.print(prompt);
				value = scanner.nextLine();
				break;
			} catch (InputMismatchException e) {
				System.out.println("输入错误，请重新输入小数。");
			}
		}
		return value;
	}
}
class Menu {
	public int selectMenu(){
		int result;

		while (true){
			try {
				for(String choice:choices) System.out.println(choice);
				result= KeyboardInput.scanner.nextInt();
				if(result>=0&&result<choices.length) {
					return result;
				}
				System.out.println("Please Enter a number between 0-"
						+(choices.length-1)
				);
			}
			catch (InputMismatchException inputMismatchException){
				System.out.println();
			}
		}

	}
	private String[] choices;
	public Menu(String[] options) {
		this.choices = options;
	}

}
public class Main {
	public static void main(String[] args) {
		BankSystem bankSystem=new BankSystem();
		bankSystem.mainMenu();
	}
}
abstract class Card {
	String account;
	String password;
	double balance;
	public String getAccount() {
		return account;
	}
	Card(String account){
		Scanner scanner=new Scanner(System.in);
		this.account=account;
		System.out.println("请输入密码");
		this.password=scanner.next();
		System.out.println("注册成功");
		this.balance= BankMenu.getDigit("请输入初始余额：");
	}
	boolean checkPassword(String trial){
		return trial.equals(this.password);
	}
	void ATM(){
		while (true)
		{
			String[] choices = {
					"1.存款",
					"2.取款",
					"3.查询余额",
					"0.登出账号"
			};
			switch (BankMenu.selectMenu(choices)) {
				case 1:
					this.deposit(BankMenu.getDigit("请输入存入金额") );
					break;
				case 2:
					this.withdraw(BankMenu.getDigit("请输入取款金额"));
					break;
				case 3:
					this.show();
					break;
				case 0:
					return;
			}
		}
	}
	void show(){
		System.out.println("账号：\t"+this.account);
		System.out.println("余额：\t"+this.balance);
	}
	void deposit(double amount){
		this.balance+=amount;
	}
	abstract void withdraw(double amount);
	abstract void consume(double amount);
}
class DepositCard extends Card{
	DepositCard(String account) {
		super(account);
	}

	@Override
	void show() {
		super.show();
		System.out.println("类型：\t储值卡");
	}

	void withdraw(double amount){
		boolean res=amount<=this.balance;
		if(res) this.balance-=amount;
		else System.out.println("余额不足，无法提款");
	}
	void consume(double amount){
		boolean res=amount<=this.balance;
		if(res) this.balance-=amount;
		else System.out.println("余额不足，无法消费");
	}
}
class CreditCard extends Card{
	final int NEGATIVE_LIM=1000;
	CreditCard(String account) {super(account);}
	@Override
	void show() {
		super.show();
		System.out.println("类型：\t信用卡");
	}
	@Override
	void withdraw(double amount) {
		boolean res=
				amount<=(this.balance+this.NEGATIVE_LIM);
		if(res) {
			this.balance-=amount;
			if(this.balance<0) System.out.println("您已透支，请及时充值");
		}
		else System.out.println("您已达到透支额度，无法提款");
	}
	@Override
	void consume(double amount) {
		boolean res=
				amount<=(this.balance+this.NEGATIVE_LIM);
		if(res) {
			this.balance-=amount;
			if(this.balance<0) System.out.println("您已透支，请及时充值");
		}
		else System.out.println("您已达到透支额度，无法消费");
	}
}
class BankMenu {
	static Scanner scanner=new Scanner(System.in);
	static int selectMenu(String[] choices){
		int result;
		while (true){
			try {
				for(String choice:choices)
					System.out.println(choice);
				result=scanner.nextInt();
				if(result>=0&&result<choices.length)
					return result;
				else System.out.println("无此选项");
				System.out.println("选择失败");
				System.out.println("请再试一次");
			}
			catch (InputMismatchException inputMismatchException){
				System.out.println("无效数字");
			}
		}
	}
	static float getDigit(String prompt){
		float result;
		while (true){
			try {
				System.out.println(prompt);
				result=scanner.nextFloat();
				return result;
			}
			catch (InputMismatchException inputMismatchException){
				System.out.println("无效数字");
				System.out.println("请再试一次");
			}
		}
	}

}
class BankSystem{
	static LinkedList<Card> cardCollection=new LinkedList<>();
	public static Card findAccount(String name,
								   boolean create){
		for(Card card:cardCollection){
			if(name.equals(card.getAccount()))
				return card;
		}
		if(!create)
			System.out.println("账号或密码错误");
		return null;
	}
	void mainMenu(){
		String[] choices={"1.开户","2.ATM(存、取款、查询账户)","3.消费pos机","0.退出"};
		Scanner scanner=new Scanner(System.in);
		Card thisCard=null;
		String account;
		while (true)
			switch (BankMenu.selectMenu(choices)){
				case 1:
					thisCard=initAccount();
					if(thisCard!=null)
						cardCollection.add(thisCard);
					else System.out.println("注册失败");
					break;
				case 2:
					while (thisCard==null){
						System.out.println("请输入账号和密码(输入0退出)");
						account=scanner.next();
						if(account.equals("0")) {
							System.out.println("欢迎下次使用！");
							break;
						}
						thisCard=findAccount(account,false);
						if(thisCard==null) System.out.println("账号未注册，请重试");
						else if (thisCard.checkPassword(scanner.next()))
							break;
						else System.out.println("无对应账号密码\n请再试一次");
					}
					thisCard.show();
					thisCard.ATM();
					thisCard=null;
					break;
				case 3:
					while (thisCard==null){
						System.out.println("请输入账号和密码(输入0退出)");
						account=scanner.next();
						if(account.equals("0")) {
							System.out.println("欢迎下次使用！");
							break;
						}
						thisCard=findAccount(account,false);
						if(thisCard==null) System.out.println("账号未注册，请重试");
						else if (thisCard.checkPassword(scanner.next()))
							break;
						else {
							thisCard=null;
							System.out.println("无对应账号密码\n请再试一次");
						}
					}
					thisCard.consume(
							BankMenu.getDigit("请输入消费金额：")
					);
					thisCard=null;
					break;
				case 0:
					System.out.println("欢迎下次使用");
					return;
			}
	}
	Card initAccount(){
		String[] choices={"请选择申请的卡的类型：\n1.储蓄卡","2.信用卡","0.返回上一界面"};
		Scanner scanner=new Scanner(System.in);
		String account;
		int choice= BankMenu.selectMenu(choices);
		while (true) {
			System.out.println("请输入账号");
			account=scanner.next();
			if(findAccount(account,true)==null)break;
			else System.out.println("账号已注册");
		}
		return switch (choice) {
			case 1 -> new DepositCard(account);
			case 2 -> new CreditCard(account);
			default -> null;
		};
	}
}
